package cn.ztydata.teachingsystem.heaven.web.interceptor;

import cn.ztydata.teachingsystem.heaven.common.WebContext;
import cn.ztydata.teachingsystem.heaven.entity.User;
import cn.ztydata.teachingsystem.heaven.web.wrapper.HttpSessionProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 认证拦截器
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {
    private final static Logger log = LoggerFactory.getLogger(AuthInterceptor.class);

    @Value("${session.key}")
    private String sessionKey;

    @Autowired
    private WebContext webContext;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //如果是跨域授权请求，直接放行
        if("OPTIONS".equals(request.getMethod())){
            log.debug("跨域请求:OPTIONS.equals(request.getMethod())");

            return true;
        }

        String sessionId = "";
        if (request.getHeader("auth") != null && !"".equals(request.getHeader("auth"))) {//获取请求头中携带的sessionId
            log.debug("获取请求头中携带的auth");

            sessionId = request.getHeader("auth");
        } else if (request.getParameter("auth") != null && !"".equals(request.getParameter("auth"))) {//获取URL中携带的sessionId
            log.debug("获取URL中携带的auth");

            sessionId = (String) request.getParameter("auth");
        }

        if(sessionId.isEmpty()){
            log.debug("未获取到auth:sessionId.isEmpty()");

            log.warn("该请求("+request.getRequestURI()+")没有携带对应的会话id");

            throw new Exception("该请求("+request.getRequestURI()+")没有携带对应的会话id");
        }

        //初始化session
        HttpSessionProxy httpSession = (HttpSessionProxy)request.getSession();
        httpSession.init(sessionId);

        //通过sessionid换取当前登录用户的真实userId
        User userInfo = (User)httpSession.getAttribute(sessionKey);

        if(userInfo == null){
            log.debug("未获取到登录用户信息:userInfo == null");

            log.warn("当前用户没有登录信息");

            response.setStatus(401);
            return false;
        }

        request.setAttribute("userId", String.valueOf(userInfo.getUserId()));

        //登录用户ID保存到web上下文
        webContext.setUserId(userInfo.getUserId());
        //保存登录用户的账号
        webContext.setAccount(userInfo.getNumber());
        //保存登录用户所选角色
        webContext.setRole(userInfo.getRole());
        //保存应用根目录的物理路径
        webContext.setRootDirPath(getPhysicalPath(request, "/"));

        log.debug("return true");

        return true;
    }

    /**
     * 获取物理路径
     *
     * @param request http请求
     * @param uri 请求uri
     * @return String 物理路径
     *
     * @author cx
     * @since 2014-05-05
     */
    private String getPhysicalPath(HttpServletRequest request, String uri) {
        HttpSession session = request.getSession();
        ServletContext servletContext = session.getServletContext();
        String realPath = servletContext.getRealPath(uri);

        log.debug("return request realPath");

        return realPath;
    }
}
